package com.lry.netty01.rx;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.oio.OioEventLoopGroup;
import io.netty.channel.rxtx.RxtxChannel;
import io.netty.channel.rxtx.RxtxChannelConfig;
import io.netty.channel.rxtx.RxtxDeviceAddress;
import io.netty.handler.timeout.IdleStateHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;


@Component
@Slf4j
public class SerialClient {

    private  EventLoopGroup group,business;

    public static void main(String[] args) {
        SerialClient client = new SerialClient();
        client.run(args);
    }

    public void run(String[]args){
        ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("tq-serial-business-%d").setDaemon(false).build();
        //业务线程
        business = new NioEventLoopGroup(5,threadFactory);
        //通信
        group = new OioEventLoopGroup();


        connect("COM3",4800);

        shutDownHook();
    }


    public void connect(String com,Integer bort)   {
        log.info("com="+com+" bort="+bort+" checkBit="+0);


        ChannelFuture future = null;
        try {
            future = getBootstrap(bort,0).connect(new RxtxDeviceAddress(com)).sync();
        } catch (Exception e) {
            log.info("linux服务器没有串口"+com);
            return;
        }

        if(future.isSuccess()){
            log.info("连接"+com+"串口成功");
            return;
        }
        log.info("连接"+com+"串口失败");
    }

    private Bootstrap getBootstrap(int bort,int checkBit){
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.channelFactory(()->{
            return getChannel(bort,checkBit);
        });
        bootstrap.group(group)
                .handler(new ChannelInitializer<RxtxChannel>() {
                    @Override
                    public void initChannel(RxtxChannel ch) throws Exception {
                        ch.pipeline().addLast(new FrameDecoder(1024));
                        ch.pipeline().addLast("decoder", new PacketDecoder());
                        ch.pipeline().addLast("encoder", new PacketEncoder());
                        ch.pipeline().addLast(new PacketHandler());
                    }
                });
        return bootstrap;
    }


    private RxtxChannel getChannel(int baudrate,int checkBit){
        //就是该类用于串口通讯
        RxtxChannel channel = new RxtxChannel();
        //设置波特率
        channel.config().setBaudrate(baudrate);
        //设置数据位
        channel.config().setDatabits(RxtxChannelConfig.Databits.DATABITS_8);
        if(checkBit==0){
            //设置校验位
            channel.config().setParitybit(RxtxChannelConfig.Paritybit.NONE);
        }else if(checkBit==1){
            //设置校验位
            channel.config().setParitybit(RxtxChannelConfig.Paritybit.ODD);
        }else if(checkBit==2){
            //设置校验位
            channel.config().setParitybit(RxtxChannelConfig.Paritybit.EVEN);
        }
        //设置停止位
        channel.config().setStopbits(RxtxChannelConfig.Stopbits.STOPBITS_1);

        return channel;
    }

    private void shutDownHook() {
        Runtime.getRuntime().addShutdownHook(new Thread(()-> {
            log.info("服务器关闭，开始释放串口资源，记录设备下线时间");
            releaseResource();
        }));
    }


    private void releaseResource() {
        try {
            if(group!=null) {
                group.shutdownGracefully().sync();
            }
            if(business!=null) {
                business.shutdownGracefully().sync();
            }
        } catch (InterruptedException e) {
            log.info("group business shutdown 异常");
            e.printStackTrace();
        }
    }


}


